home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-03 | 6.9 KB | 280 lines | [TEXT/MSET] |
- \ Support for named parms and local variables
-
- 24 constant MAXPL \ Should be enough!!
- false value LOCFLG \ true = looking for local var tokens
-
-
- create PARMLIST maxPL cells reserve
-
- 0 value SVHASH
- false value FLOAT?
- 0 value PLentry_addr
-
-
- : INITLOCS \ Initializes flags etc.
- 0 -> #PL 0 -> #P 0 -> #F
- 0 -> FltFlg false -> locFlg ;
-
-
- : FINDINPARMLIST \ ( addr -- loc# T OR -- F )
- \ loc# counts from right to left in the local/parm list.
-
- dup 1+ c@ & % = -> float?
- hash -> svHash false
- #PL 0exit
- ParmList #PL 4* bounds DO
- svHash i @ =
- IF ( found )
- drop #PL
- i parmlist - 4/
- - 1- true LEAVE
- THEN
- 4 +LOOP ;
-
-
- : ADDTOPARMLIST \ ( addr -- ) Adds an element to ParmList.
- \ addr points to a counted string.
- findinParmList ?error 95 \ Name not unique
- #PL maxPL >= ?error 110
- FltFlg 1 << float? if 1 or 1 ++> #F then -> FltFlg
- svHash
- #PL 1 ++> #PL 4* ParmList + ! ;
-
-
- : FIRSTCHR
- here 1+ c@ ;
-
-
- :f {
- local? IF \ local? already non-zero - this ought to mean we're
- \ in a local section
- local? 0< ?error 92 -1 -> local?
- THEN
- initLocs
-
- BEGIN \ Loop to add parms/locals to parmlist
- Mword drop
- firstChr & - <> \ look for --
- WHILE
- firstChr dup & \ = swap & / = or
- \ Note: we allow / as an alternative to \
-
- IF true -> locFlg
- ELSE firstChr & } = ?error 111
- locFlg nif 1 ++> #P then
- here AddToParmList
- THEN
- REPEAT
- local? NIF \ In local sections, we do this at :LOC
- here -> PLentry_addr
- \ If we have temp objects, we'll have to backup the DP and
- \ recompile the entry sequence, since there'll be an extra local
- \ (the frame pointer)
- PLentry
- THEN
- & } parse 2drop \ eat characters until }
- rest nip 0< ?error 112 ;f \ Err if no final }
-
-
- \ FIND will call Pfind to attempt to find a name first.
- \ If Pfind finds the name is a local, it returns true and the
- \ cfa of LocParm, which is a dummy word whose handler compiles
- \ a local reference.
-
- : PFIND \ ( str-addr -- cfa T | -- str-addr F )
- state
- NIF false
- ELSE dup FindInParmList
- IF \ Found
- -> loc# drop
- float? IF ['] FlocParm ELSE ['] locParm THEN
- true
- ELSE false \ Not found
- THEN
- THEN ;
-
-
- : ,EXEC \ ( cfa n -- )
- state
- IF (compN) ELSE exN THEN ;
-
- \ Here are the different types that we can put prefixes on or send
- \ messages to:
-
- TYPE{ notfnd locTyp flocTyp
- tmpObjTyp objTyp ivarTyp classTyp superTyp
- valTyp fvalTyp vecTyp dynVecTyp objptrTyp wordTyp
- regTyp lbTyp lbSelfTyp bktTyp }
-
- \ notFnd - not previously defined
- \ locTyp - a local or named parm
- \ tmpObjTyp - a temporary (local) object
- \ objTyp - an object
- \ ivarTyp - an ivar
- \ classTyp - a class
- \ superTyp - a named superclass specified by msg: super> someClass
- \ valTyp - a value
- \ FvalTyp - a floating point value
- \ vecTyp - a vector
- \ dynVecTyp - a dynamic vector
- \ wordTyp - an ordinary word
- \ regTyp - a 680x0 register
- \ lbTyp - ** or [] meaning late bind
- \ lbSelfTyp - [self] meaning late bind to self
- \ BktTyp - [ - Neon-compatible late bind
-
- \ PRFTOKEN returns the type of a token for a prefix op.
-
- \ First we need to make some handler codes available above the Nucleus.
-
- : HDLR \ ( cfa -- ha )
- 2- w@x ;
-
- ' key hdlr constant VECTCODE
- ' base hdlr constant VALCODE
- ' ^base hdlr constant REGCODE
- ' hdlr hdlr constant WORDCODE
-
- objPtr XX ' xx hdlr forget xx
- constant OBJPTRCODE
- dynamicVect XX ' xx hdlr forget xx
- constant DYNVECTCODE
-
- : PRFTOKEN \ ( -- cfa type )
- ' dup ['] locParm = IF locTyp EXIT THEN
- dup ['] FlocParm = IF FlocTyp EXIT THEN
- dup hdlr
- CASE
- valCode OF valTyp ENDOF
- FvalCode OF FvalTyp ENDOF
- vectCode OF vecTyp ENDOF
- dynVectCode OF dynVecTyp ENDOF
- regCode OF regTyp ENDOF
- objPtrCode OF objPtrTyp ENDOF
- ?error 114
- ENDCASE ;
-
-
- forward ToObjPtr \ Stores to an objPtr. Defined in file Class.
-
- : -> immediate
- PrfToken \ All types are legal
- objPtrTyp = IF toObjPtr EXIT THEN
- $ 60 ( opcode for Store ) ,exec ;
- \ NOTE: opcode for store hard coded here!!!
-
- : CvrtFcode \ ( code -- code' )
- CASE
- $ 21 OF $ 41 ENDOF \ +
- $ 22 OF $ 48 ENDOF \ -
- $ 28 OF $ 55 ENDOF \ Neg
- ?error 114
- ENDCASE ;
-
- : (+->) \ ( code -- cfa code' )
- PrfToken ( code cfa type ) rot swap ( cfa code type )
-
- CASE
- locTyp OF ENDOF
- FlocTyp OF CvrtFcode ENDOF
- valTyp OF ENDOF
- FvalTyp OF CvrtFcode ENDOF
- regTyp OF ENDOF
- ?error 114
- ENDCASE ;
-
- : (FOP)
- PrfToken rot swap
- CASE
- locTyp OF ENDOF
- FlocTyp OF ENDOF
- FvalTyp OF ENDOF
- ?error 114
- ENDCASE ;
-
- \ Note: the following opcodes have to agree with the definitions in
- \ OD.asm. I could have defined them as constants but this would have
- \ used up dictionary space for no great benefit.
-
- : ++> $ 21 (+->) ,exec ; immediate
- : +> postpone ++> ; immediate \ A synonym.
- : --> $ 22 (+->) ,exec ; immediate
- : AND> $ 23 (+->) ,exec ; immediate
- : OR> $ 24 (+->) ,exec ; immediate
- : XOR> $ 25 (+->) ,exec ; immediate
- : NEG> $ 28 (+->) ,exec ; immediate
- : NOT> $ 29 (+->) ,exec ; immediate
- : *> $ 42 (fop) ,exec ; immediate
- : /> $ 49 (fop) ,exec ; immediate
- : ABS> $ 54 (fop) ,exec ; immediate
-
- ' Pfind -> Ufind
-
- \ =========== Local sections ===========
-
- forward INITTEMPS
-
- : ?LOC local? 0= ?error 91 ; \ "We're not in a local section"
-
- : LOCAL
- local? ?error 93 1 -> local? \ We change it to the normal -1
- \ as soon as "{" is read.
- forward ;
-
-
- : :LOC immediate
- local? 1 = IF msg# 96 THEN \ warning - no locals defined
- ?loc 304
- here ' (patch) :noname \ Like :F
- #PL IF PLentry THEN
- frameSize IF initTemps THEN
- false -> local? \ We do this here so any EXITs
- ; \ tidy everything up properly
-
-
- : ;LOC immediate
- (;) 304 ?defn ; \ As local? is now false, everything else
- \ gets tidied up by (;)
-
-
- \ ============================================
-
- : EVALUATE { addr len \ x1 x2 x3 x4 -- ?? }
-
- save-input drop \ Must be 4
- -> x4 -> x3 -> x2 -> x1 \ Move input-stream specs to locals
-
- addr -> src-start len -> src-len 0 >in ! -1 -> source-id
- echo? IF ." ***evaluating*** " addr len type cr THEN
- interpret
- x1 x2 x3 x4 4 restore-input ?error 25 ;
-
- \ We can EVALUATE strings which might have embedded returns, and we can't
- \ just convert returns to blanks since we want the comment operator \
- \ to only skip to the end of the line, not the end of the string. We handle
- \ this by defining an immediate "word" which just consists of a return, which
- \ does nothing. We initially define it as X then patch it. Our dic
- \ threading scheme doesn't clobber this since we just hash on the length,
- \ which remains 1.
-
- : X ; immediate
-
- 13 ( cr ) ' x >name 1+ c!
-
-
- : (COMPINL) \ ( cfa -- )
- 2+ count evaluate ;
-
- ' (compinl) -> compinline
-
- : INLINE{ immediate
- method? IF -4 allot THEN \ Wipe out method entry sequence
- \ %%% watch this on PPC!
- inlMk w, & } ,str
- align-dp
- method? IF Mentry THEN \ Recompile method entry sequence
- postpone ] ;
-
-
- <" Class
-